package com.yqwh.coder.handlerphoto;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.ImageOutputStream;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Iterator;

public class ImageUtils {
    final static Logger logger = LoggerFactory.getLogger(ImageUtils.class);

    /**
     * 此方法按照目标尺寸进行等比例压缩，压缩比取尺寸小的
     *
     * @param srcFile      String
     * @param destFile     String
     * @param destPath     String
     * @param destWidth    int
     * @param destHeight   int
     * @param destQuality  float
     * @param keepOriginal boolean
     * @param addBg        boolean
     * @param bgColor      Color
     * @param sideRate     double
     * @param signed       boolean
     * @param signName     String
     * @param signColor    Color
     * @param signOffsetX  int
     * @param signOffsetY  int
     * @return boolean
     */
    @SuppressWarnings("unused")
    private static boolean newCompressImage(String srcFile, String destPath, String destFile, int destWidth, int destHeight, float destQuality, boolean keepOriginal, boolean addBg,
                                            Color bgColor, double sideRate, boolean signed, String signName, Color signColor, int signOffsetX, int signOffsetY) {
        try {
            // 判断文件是否存在
            File srcImageFile = new File(srcFile);
            if (!srcImageFile.canRead()) {
                return false;
            }
            // 源图片属性
            FileInputStream fileInputStream = new FileInputStream(srcImageFile);
            BufferedImage srcImage = ImageIO.read(fileInputStream);
            double srcImageWidth = srcImage.getWidth();
            double srcImageHeight = srcImage.getHeight();
            int srcImageType =0;
            srcImageType=srcImage.getType();
            System.out.println(srcImageType);
            // 目标图片属性
            int destImageWidth;
            int destImageHeight;
            // 图片压缩质量
            float destImageQuality;
            // 缩放比例
            double resizeRate;
            // 绘图尺寸
            int g_destImageWidth;
            int g_destImageHeight;
            int g_destImageX = 0;
            int g_destImageY = 0;
            destImageQuality = destQuality;
            // 保持图片原始比例
            if (keepOriginal) {
                destImageWidth = destWidth;
                resizeRate = destImageWidth / srcImageWidth;
                destImageHeight = (int) (srcImageHeight * resizeRate);
                g_destImageWidth = destImageWidth;
                g_destImageHeight = destImageHeight;
            } else {
                // 用默认尺寸生成新的图片
                destImageWidth = destWidth;
                destImageHeight = destHeight;
                double widthRate = destImageWidth / srcImageWidth;
                double heightRate = destImageHeight / srcImageHeight;
                resizeRate = widthRate < heightRate ? widthRate : heightRate;
                g_destImageWidth = (int) (srcImageWidth * resizeRate);
                g_destImageHeight = (int) (srcImageHeight * resizeRate);
            }
            // 是否添加背景
            if (addBg) {
                g_destImageWidth *= (1 - sideRate);
                g_destImageHeight *= (1 - sideRate);
                g_destImageX = (destImageWidth - g_destImageWidth) / 2;
                g_destImageY = (destImageHeight - g_destImageHeight) / 2;
            }
            if (Double.valueOf(srcImageWidth).intValue() > destImageWidth || Double.valueOf(srcImageHeight).intValue() > destImageHeight) {
                destImageWidth = g_destImageWidth;
                destImageHeight = g_destImageHeight;
                BufferedImage destImage = new BufferedImage(destImageWidth, destImageHeight, srcImageType);
                // 用Graphics2D 还是 Graphics 绘图
                Graphics g = destImage.getGraphics();
                if (addBg) {
                    g.setColor(bgColor);
                    g.fillRect(0, 0, destImageWidth, destImageHeight);
                }
                ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
                g.drawImage(srcImage, g_destImageX, g_destImageY, g_destImageWidth, g_destImageHeight, bgColor, null);
                if (signed) {
                    g.setColor(signColor);
                    g.drawString("Photo by " + signName, destImageWidth - signOffsetX, destImageHeight - signOffsetY);
                }
                g.dispose();
                File destFilePath = new File(destPath);
                if (!destFilePath.exists()) {
                    destFilePath.mkdirs();
                }
                ImageIO.write(destImage, srcFile.substring(srcFile.lastIndexOf(".")+1,srcFile.length()), new File(destPath+destFile));
                fileInputStream.close();
            } else {
                File destFilePath = new File(destPath);
                if (!destFilePath.exists()) {
                    destFilePath.mkdirs();
                }
                FileOutputStream out = new FileOutputStream(destPath + destFile);
                FileInputStream in = new FileInputStream(new File(srcFile));
                int i = in.read();
                int index = 0;
                while (i != -1) {
                    out.write((char) i);
                    index++;
                    i = in.read();
                }
                in.close();
                out.close();
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return false;
        }
        return true;
    }

    /*
     * 此方法按照目标尺寸进行等比例压缩，压缩比取尺寸小的
     *
     * @param height   高度
     * @param width    宽度
     * @param srcFile  String
     * @param destFile String
     * @param destPath String
     * @return boolean
     */
    public static boolean newCreateIconSmall(String srcFile, String destPath, String destFile, int width, int height) {
        return ImageUtils.newCompressImage(srcFile, destPath, destFile, width, height, 1.0f, false, false, null, 0.05, false, null, null, 0, 0);
    }
    
    /*
     * 裁剪图片
     *
     * @param originalPath String
     * @param destPath     String
     * @param fileName     String
     * @param x            int
     * @param y            int
     * @param width        int
     * @param height       int
     */
    public static void cutting(String originalPath, String destPath, String fileName, int x, int y, int width, int height) {
        ImageReader reader = null;
        InputStream is = null;
        ImageInputStream iis = null;
        ImageOutputStream out = null;
        try {
            File originalFile = new File(originalPath, fileName);
            String endName = originalFile.getName();
            endName = endName.substring(endName.lastIndexOf(".") + 1);
            Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName(endName);
            reader = readers.next();
            is = new FileInputStream(originalFile);
            iis = ImageIO.createImageInputStream(is);
            reader.setInput(iis, true);
            ImageReadParam param = reader.getDefaultReadParam();
            Rectangle rect = new Rectangle(x, y, width, height);
            param.setSourceRegion(rect);
            BufferedImage bi = reader.read(0, param);
            //path = path + "[url=file://\\]\\" + width + "-" + height + "[/url]";
            File destFile = new File(destPath);
            if (!destFile.exists())
                destFile.mkdirs();
            destFile = new File(destPath, fileName);
            out = ImageIO.createImageOutputStream(new FileOutputStream(destFile));
            ImageIO.write(bi, endName, out);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
//			e.printStackTrace();
        } finally {
            if (reader != null) {
                reader.dispose();
            }
            try {
                if (is != null) is.close();
                if (iis != null) iis.close();
                if (out != null) out.close();
            } catch (IOException e) {
                logger.error(e.getMessage(), e);
//				e.printStackTrace();
            }
        }
    }
    /*
     * 此方法先对图片进行等比例压缩，压缩比取尺寸大的，然后进行裁剪，裁剪取中间部分
     *
     * @param height   高度
     * @param width    宽度
     * @param srcFile  String
     * @param destFile String
     * @param destPath String
     * @return boolean
     */
    public static boolean cutCompressImage(String srcFile, String destPath, String destFile, int height, int width) {
        return ImageUtils.cutCompressImage(srcFile, destPath, destFile, height, width, 1.0f, false, false, null, 0.05, false, null, null, 0, 0);
    }

    /*
     * 按指定大小压缩图片
     *
     * @param height   高度
     * @param width    宽度
     * @param srcFile  String
     * @param destFile String
     * @param destPath String
     * @return boolean
     */
    public static boolean createIcon(String srcFile, String destPath, String destFile, int height, int width) {
        return ImageUtils.compressImage(srcFile, destPath, destFile, height, width, 1.0f, false, true, null, 0.05, false, null, null, 0, 0);
    }
    /*
     * @param srcFile      String
     * @param destFile     String
     * @param destPath     String
     * @param destWidth    int
     * @param destHeight   int
     * @param destQuality  int
     * @param keepOriginal boolean
     * @param addBg        boolean
     * @param bgColor      Color
     * @param sideRate     double
     * @param signed       boolean
     * @param signName     String
     * @param signColor    Color
     * @param signOffsetX  int
     * @param signOffsetY  int
     * @return boolean
     */

    private static boolean compressImage(String srcFile, String destPath, String destFile, int destWidth, int destHeight, float destQuality, boolean keepOriginal, boolean addBg, Color bgColor,
                                         double sideRate, boolean signed, String signName, Color signColor, int signOffsetX, int signOffsetY) {
        try {
            // 判断文件是否存在
            File srcImageFile = new File(srcFile);
            if (!srcImageFile.canRead()) {
                return false;
            }
            // 源图片属性
            FileInputStream fileInputStream = new FileInputStream(srcImageFile);
            BufferedImage srcImage = ImageIO.read(fileInputStream);
            double srcImageWidth = srcImage.getWidth();
            double srcImageHeight = srcImage.getHeight();
            int srcImageType = srcImage.getType();
            // 目标图片属性
            int destImageWidth;
            int destImageHeight;
            // 图片压缩质量
            float destImageQuality;
            // 缩放比例
            double resizeRate;
            // 绘图尺寸
            int g_destImageWidth;
            int g_destImageHeight;
            int g_destImageX = 0;
            int g_destImageY = 0;
            destImageQuality = destQuality;
            // 保持图片原始比例
            if (keepOriginal) {
                destImageWidth = destWidth;
                resizeRate = destImageWidth / srcImageWidth;
                destImageHeight = (int) (srcImageHeight * resizeRate);
                g_destImageWidth = destImageWidth;
                g_destImageHeight = destImageHeight;
            } else {
                // 用默认尺寸生成新的图片
                destImageWidth = destWidth;
                destImageHeight = destHeight;
                double widthRate = destImageWidth / srcImageWidth;
                double heightRate = destImageHeight / srcImageHeight;
                resizeRate = widthRate < heightRate ? widthRate : heightRate;
                g_destImageWidth = (int) (srcImageWidth * resizeRate);
                g_destImageHeight = (int) (srcImageHeight * resizeRate);
            }
            // 是否添加背景
            if (addBg) {
                g_destImageWidth *= (1 - sideRate);
                g_destImageHeight *= (1 - sideRate);
                g_destImageX = (destImageWidth - g_destImageWidth) / 2;
                g_destImageY = (destImageHeight - g_destImageHeight) / 2;
            }
            BufferedImage destImage = new BufferedImage(destImageWidth, destImageHeight, srcImageType);
            // 用Graphics2D 还是 Graphics 绘图
            Graphics g = destImage.getGraphics();
            if (addBg) {
                g.setColor(bgColor);
                g.fillRect(0, 0, destImageWidth, destImageHeight);
            }
            //if (true) {
            ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g.drawImage(srcImage, g_destImageX, g_destImageY, g_destImageWidth, g_destImageHeight, bgColor, null);
//			} else {
//				g.setColor(bgColor);
//				g.fillRect(0, 0, destImageWidth, destImageHeight);
//				g.drawImage(srcImage.getScaledInstance(g_destImageWidth, g_destImageHeight, Image.SCALE_FAST), g_destImageX, g_destImageY, null);
//			}
            if (signed) {
                g.setColor(signColor);
                g.drawString("Photo by " + signName, destImageWidth - signOffsetX, destImageHeight - signOffsetY);
            }
            g.dispose();
            File destFilePath = new File(destPath);
            if (!destFilePath.exists()) {
                destFilePath.mkdirs();
            }
            FileOutputStream out = new FileOutputStream(destPath + destFile);
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
            JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(destImage);
            param.setQuality(destImageQuality, false);
            encoder.setJPEGEncodeParam(param);
            encoder.encode(destImage);
            out.close();
            fileInputStream.close();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
//			e.printStackTrace();
            return false;
        }
        return true;
    }
    /**
     * 此方法先对图片进行等比例压缩，压缩比取尺寸大的，然后进行裁剪，裁剪取中间部分
     *
     * @param srcFile      String
     * @param destPath     String
     * @param destFile     String
     * @param destWidth    int
     * @param destHeight   int
     * @param destQuality  float
     * @param keepOriginal boolean
     * @param addBg        boolean
     * @param bgColor      Color
     * @param sideRate     double
     * @param signed       boolean
     * @param signName     String
     * @param signColor    Color
     * @param signOffsetX  int
     * @param signOffsetY  int
     * @return boolean
     */
    @SuppressWarnings("unused")
    private static boolean cutCompressImage(String srcFile, String destPath, String destFile, int destWidth, int destHeight, float destQuality, boolean keepOriginal, boolean addBg,
                                            Color bgColor, double sideRate, boolean signed, String signName, Color signColor, int signOffsetX, int signOffsetY) {
        try {
            // 判断文件是否存在
            File srcImageFile = new File(srcFile);
            if (!srcImageFile.canRead()) {
                return false;
            }
            // 源图片属性
            FileInputStream fileInputStream = new FileInputStream(srcImageFile);
            BufferedImage srcImage = ImageIO.read(fileInputStream);
            double srcImageWidth = srcImage.getWidth();
            double srcImageHeight = srcImage.getHeight();
            int srcImageType = srcImage.getType();
            // 目标图片属性
            int destImageWidth;
            int destImageHeight;
            // 图片压缩质量
            float destImageQuality;
            // 缩放比例
            double resizeRate;
            // 绘图尺寸
            int g_destImageWidth;
            int g_destImageHeight;
            int g_destImageX = 0;
            int g_destImageY = 0;
            destImageQuality = destQuality;
            // 保持图片原始比例
            if (keepOriginal) {
                destImageWidth = destWidth;
                resizeRate = destImageWidth / srcImageWidth;
                destImageHeight = (int) (srcImageHeight * resizeRate);
                g_destImageWidth = destImageWidth;
                g_destImageHeight = destImageHeight;
            } else {
                // 用默认尺寸生成新的图片
                destImageWidth = destWidth;
                destImageHeight = destHeight;
                double widthRate = destImageWidth / srcImageWidth;
                double heightRate = destImageHeight / srcImageHeight;
                resizeRate = widthRate > heightRate ? widthRate : heightRate;
                g_destImageWidth = (int) (srcImageWidth * resizeRate);
                g_destImageHeight = (int) (srcImageHeight * resizeRate);
            }
            // 是否添加背景
            if (addBg) {
                g_destImageWidth *= (1 - sideRate);
                g_destImageHeight *= (1 - sideRate);
                g_destImageX = (destImageWidth - g_destImageWidth) / 2;
                g_destImageY = (destImageHeight - g_destImageHeight) / 2;
            }
            if (Double.valueOf(srcImageWidth).intValue() > destImageWidth || Double.valueOf(srcImageHeight).intValue() > destImageHeight) {
                // destImageWidth = Double.valueOf(srcImageWidth).intValue();
                // destImageHeight = Double.valueOf(srcImageHeight).intValue();
                destImageWidth = g_destImageWidth;
                destImageHeight = g_destImageHeight;
                BufferedImage destImage = new BufferedImage(destImageWidth, destImageHeight, srcImageType);
                // 用Graphics2D 还是 Graphics 绘图
                Graphics g = destImage.getGraphics();
                if (addBg) {
                    g.setColor(bgColor);
                    g.fillRect(0, 0, destImageWidth, destImageHeight);
                }
//				if (true) {
                ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
                g.drawImage(srcImage, g_destImageX, g_destImageY, g_destImageWidth, g_destImageHeight, bgColor, null);
//				} else {
//					g.setColor(bgColor);
//					g.fillRect(0, 0, destImageWidth, destImageHeight);
//					g.drawImage(srcImage.getScaledInstance(g_destImageWidth, g_destImageHeight, Image.SCALE_FAST), g_destImageX, g_destImageY, null);
//				}
                if (signed) {
                    g.setColor(signColor);
                    g.drawString("Photo by " + signName, destImageWidth - signOffsetX, destImageHeight - signOffsetY);
                }
                g.dispose();
                File destFilePath = new File(destPath);
                if (!destFilePath.exists()) {
                    destFilePath.mkdirs();
                }
                ImageIO.write(destImage, srcFile.substring(srcFile.lastIndexOf(".")+1,srcFile.length()), new File(destPath+destFile));                
                fileInputStream.close();
                String cutname = destPath + destFile;
                int cutx = destImageWidth - destWidth;
                int cuty = destImageHeight - destHeight;
                ImageCutUtil cutUtil = new ImageCutUtil(cutx > 0 ? cutx / 2 : 0, cuty > 0 ? cuty / 2 : 0, destWidth, destHeight);
                cutUtil.setSrcpath(cutname);
                cutUtil.setSubpath(cutname);
                cutUtil.cut();
            } else {
                File destFilePath = new File(destPath);
                if (!destFilePath.exists()) {
                    destFilePath.mkdirs();
                }
                // BufferedImage destImage = new BufferedImage(destImageWidth,
                // destImageHeight, srcImageType);
                FileOutputStream out = new FileOutputStream(destPath + destFile);
                FileInputStream in = new FileInputStream(new File(srcFile));
                int i = in.read();
                int index = 0;
                while (i != -1) {
                    out.write((char) i);
                    index++;
                    i = in.read();
                }
                in.close();
                out.close();
                // fileInputStream.close();
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
//			e.printStackTrace();
            return false;
        }
        return true;
    }    
}
